﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Issues.GangLeaderNeedsSpecialWeaponsIssueBehavior
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System;
using System.Collections.Generic;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CampaignBehaviors;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.Conversation;
using TaleWorlds.CampaignSystem.CraftingSystem;
using TaleWorlds.CampaignSystem.Extensions;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Issues
{
  public class GangLeaderNeedsSpecialWeaponsIssueBehavior : CampaignBehaviorBase
  {
    private const IssueBase.IssueFrequency SpecialWeaponOrderIssueFrequency = IssueBase.IssueFrequency.VeryCommon;

    public override void RegisterEvents()
    {
      CampaignEvents.OnCheckForIssueEvent.AddNonSerializedListener((object) this, new Action<Hero>(this.OnCheckForIssue));
    }

    private void OnCheckForIssue(Hero hero)
    {
      Campaign.Current.IssueManager.AddPotentialIssueData(hero, this.ConditionsHold(hero) ? new PotentialIssueData(new PotentialIssueData.StartIssueDelegate(this.OnStartIssue), typeof (GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssue), IssueBase.IssueFrequency.VeryCommon) : new PotentialIssueData(typeof (GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssue), IssueBase.IssueFrequency.VeryCommon));
    }

    private bool ConditionsHold(Hero issueGiver)
    {
      return issueGiver.CurrentSettlement != null && issueGiver.IsGangLeader && issueGiver.CurrentSettlement.IsTown && Campaign.Current.GetCampaignBehavior<ICraftingCampaignBehavior>() != null;
    }

    private IssueBase OnStartIssue(in PotentialIssueData pid, Hero issueOwner)
    {
      return (IssueBase) new GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssue(issueOwner);
    }

    public override void SyncData(IDataStore dataStore)
    {
    }

    public class GangLeaderNeedsSpecialWeaponsIssue : IssueBase
    {
      private const int IssueAndQuestDuration = 30;

      internal static void AutoGeneratedStaticCollectObjectsGangLeaderNeedsSpecialWeaponsIssue(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      public int NumberOfDaggersRequested => 2 + MathF.Ceiling(4f * this.IssueDifficultyMultiplier);

      public int BaseGoldRewardPerDagger
      {
        get => 200 + MathF.Ceiling(500f * this.IssueDifficultyMultiplier);
      }

      public override bool IsThereAlternativeSolution => false;

      public override bool IsThereLordSolution => false;

      protected override bool IssueQuestCanBeDuplicated => false;

      public GangLeaderNeedsSpecialWeaponsIssue(Hero issueOwner)
        : base(issueOwner, CampaignTime.DaysFromNow(30f))
      {
      }

      public override TextObject IssueBriefByIssueGiver
      {
        get
        {
          return new TextObject("{=fmjWsUB6}Yeah... I've heard about your skills as a crafter of weapons. Now, nothing inspires my lads to shed my enemies' blood than the feel of a really well-made blade in their hands. Could you make me some? I'll pay well.");
        }
      }

      public override TextObject IssueAcceptByPlayer
      {
        get => new TextObject("{=UdnXHLSh}What do you want exactly?");
      }

      public override TextObject IssueQuestSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject explanationByIssueGiver = new TextObject("{=xmETCOam}Daggers. Good, sharp, light daggers that they can hide under their clothes, so the guards won't stop them. We want to order {REQUESTED_AMOUNT} daggers and I guarantee a minimum of {REWARD_PER_DAGGER} denars for each, more if they're of exceptional quality. Also I can arrange things with the smith of {QUEST_SETTLEMENT} for you to work in his workshop.");
          explanationByIssueGiver.SetTextVariable("REQUESTED_AMOUNT", this.NumberOfDaggersRequested);
          explanationByIssueGiver.SetTextVariable("REWARD_PER_DAGGER", this.BaseGoldRewardPerDagger);
          explanationByIssueGiver.SetTextVariable("QUEST_SETTLEMENT", this.IssueOwner.CurrentSettlement.Name);
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssueQuestSolutionAcceptByPlayer
      {
        get => new TextObject("{=goLdeLsT}Alright I will forge your daggers.");
      }

      public override TextObject Title => new TextObject("{=tm9PiOMA}Special Weapon Order");

      public override TextObject Description
      {
        get
        {
          TextObject to = new TextObject("{=auIV2JoK}{ISSUE_GIVER.LINK} is looking for someone to craft special weapons for {?ISSUE_GIVER.GENDER}her{?}his{\\?} men.");
          to.SetCharacterProperties("ISSUE_GIVER", this.IssueOwner.CharacterObject);
          return to;
        }
      }

      public override IssueBase.IssueFrequency GetFrequency()
      {
        return IssueBase.IssueFrequency.VeryCommon;
      }

      protected override bool CanPlayerTakeQuestConditions(
        Hero issueGiver,
        out IssueBase.PreconditionFlags flag,
        out Hero relationHero,
        out SkillObject skill)
      {
        flag = IssueBase.PreconditionFlags.None;
        relationHero = issueGiver;
        skill = DefaultSkills.Crafting;
        if ((double) issueGiver.GetRelationWithPlayer() < -10.0)
          flag |= IssueBase.PreconditionFlags.Relation;
        if (FactionManager.IsAtWarAgainstFaction(issueGiver.MapFaction, Hero.MainHero.MapFaction))
          flag |= IssueBase.PreconditionFlags.AtWar;
        if (Hero.MainHero.GetSkillValue(skill) < 30)
          flag |= IssueBase.PreconditionFlags.Skill;
        return flag == IssueBase.PreconditionFlags.None;
      }

      protected override float GetIssueEffectAmountInternal(IssueEffect issueEffect)
      {
        if (issueEffect == DefaultIssueEffects.IssueOwnerPower)
          return -0.1f;
        return issueEffect == DefaultIssueEffects.SettlementSecurity ? 0.5f : 0.0f;
      }

      public override bool IssueStayAliveConditions() => true;

      protected override void CompleteIssueWithTimedOutConsequences()
      {
      }

      protected override void OnGameLoad()
      {
      }

      protected override QuestBase GenerateIssueQuest(string questId)
      {
        return (QuestBase) new GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest(questId, this.IssueOwner, this.NumberOfDaggersRequested, this.BaseGoldRewardPerDagger, CampaignTime.DaysFromNow(30f), this.RewardGold);
      }

      protected override void HourlyTick()
      {
      }
    }

    public class GangLeaderNeedsSpecialWeaponsIssueQuest : QuestBase
    {
      [SaveableField(1)]
      private readonly int _numberOfDaggersRequested;
      [SaveableField(2)]
      private readonly int _baseGoldRewardPerDagger;
      [SaveableField(3)]
      private CraftingOrder _currentCraftingOrder;
      [SaveableField(4)]
      private int _completedCraftingOrders;
      [SaveableField(5)]
      private JournalLog _playerAcceptedQuestLog;
      [SaveableField(6)]
      private JournalLog _playerHasNeededItemsLog;
      private const int SuccessRelationBonus = 5;
      private const int SuccessPowerBonus = 10;
      private const int FailRelationPenalty = -5;
      private const int FailPowerPenalty = -10;
      private const int MaxCraftingOrderDifficulty = 100;
      private const int CraftingOrderDifficultyVariance = 10;
      private const int MaxNumberOfCraftingOrdersAvailable = 10;
      private const string DaggerCraftingTemplateId = "Dagger";
      private ICraftingCampaignBehavior _craftingBehavior;

      internal static void AutoGeneratedStaticCollectObjectsGangLeaderNeedsSpecialWeaponsIssueQuest(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._currentCraftingOrder);
        collectedObjects.Add((object) this._playerAcceptedQuestLog);
        collectedObjects.Add((object) this._playerHasNeededItemsLog);
      }

      internal static object AutoGeneratedGetMemberValue_numberOfDaggersRequested(object o)
      {
        return (object) ((GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest) o)._numberOfDaggersRequested;
      }

      internal static object AutoGeneratedGetMemberValue_baseGoldRewardPerDagger(object o)
      {
        return (object) ((GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest) o)._baseGoldRewardPerDagger;
      }

      internal static object AutoGeneratedGetMemberValue_currentCraftingOrder(object o)
      {
        return (object) ((GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest) o)._currentCraftingOrder;
      }

      internal static object AutoGeneratedGetMemberValue_completedCraftingOrders(object o)
      {
        return (object) ((GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest) o)._completedCraftingOrders;
      }

      internal static object AutoGeneratedGetMemberValue_playerAcceptedQuestLog(object o)
      {
        return (object) ((GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest) o)._playerAcceptedQuestLog;
      }

      internal static object AutoGeneratedGetMemberValue_playerHasNeededItemsLog(object o)
      {
        return (object) ((GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest) o)._playerHasNeededItemsLog;
      }

      public override bool IsRemainingTimeHidden => false;

      private TextObject QuestStartedLog
      {
        get
        {
          TextObject to = new TextObject("{=zo1shYCL}{QUEST_GIVER.LINK} told you that {?QUEST_GIVER.GENDER}her{?}his{\\?} men need a special dagger that should be light and small enough to hide from the city guards. {?QUEST_GIVER.GENDER}She{?}He{\\?} asked you to forge {REQUESTED_AMOUNT} daggers at the smith of {QUEST_SETTLEMENT}. {?QUEST_GIVER.GENDER}She{?}He{\\?} guaranteed to pay at least {REWARD_PER_ITEM} denars for each dagger and he is ready to pay extra depending on the quality of the weapons.");
          to.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject);
          to.SetTextVariable("REQUESTED_AMOUNT", this._numberOfDaggersRequested);
          to.SetTextVariable("REWARD_PER_ITEM", this._baseGoldRewardPerDagger);
          to.SetTextVariable("QUEST_SETTLEMENT", this.QuestGiver.CurrentSettlement.Name);
          return to;
        }
      }

      private TextObject QuestSuccessLog
      {
        get
        {
          TextObject to = new TextObject("{=3uvbVxfx}You have delivered the weapons to {QUEST_GIVER.LINK} as promised.");
          to.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject);
          return to;
        }
      }

      private TextObject QuestCanceledWarDeclaredLog
      {
        get
        {
          TextObject parent = new TextObject("{=vW6kBki9}Your clan is now at war with {QUEST_GIVER.LINK}'s realm. Your agreement with {QUEST_GIVER.LINK} is canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject QuestFailedLog
      {
        get
        {
          TextObject parent = new TextObject("{=iTgVn26a}You have failed to bring the weapons to {QUEST_GIVER.LINK} in time.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      public override TextObject Title => new TextObject("{=tm9PiOMA}Special Weapon Order");

      private TextObject PlayerHasNeededItemsLogText
      {
        get
        {
          TextObject to = new TextObject("{=kHio2hlU}You now have enough daggers to complete the quest. Return to {QUEST_GIVER.LINK} to hand them over.");
          to.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject);
          return to;
        }
      }

      public GangLeaderNeedsSpecialWeaponsIssueQuest(
        string questId,
        Hero questGiver,
        int numberOfDaggersRequested,
        int baseGoldRewardPerDagger,
        CampaignTime duration,
        int rewardGold)
        : base(questId, questGiver, duration, rewardGold)
      {
        this._numberOfDaggersRequested = numberOfDaggersRequested;
        this._baseGoldRewardPerDagger = baseGoldRewardPerDagger;
        this._craftingBehavior = Campaign.Current.GetCampaignBehavior<ICraftingCampaignBehavior>();
        this.SetDialogs();
        this.InitializeQuestOnCreation();
      }

      protected override void SetDialogs()
      {
        TextObject npcText1 = new TextObject("{=siofh72D}Thank you, my friend. I'm looking forward to giving my boys their new toys.");
        TextObject npcText2 = new TextObject("{=cJOGUpSS}Any news about my orders?");
        TextObject text1 = new TextObject("{=R9NDaOhb}The daggers are almost ready. They just need a little more work...");
        TextObject npcText3 = new TextObject("{=CDXUehf0}Good, good.");
        TextObject text2 = new TextObject("{=wErSpkjy}I'm still working on it.");
        TextObject npcText4 = new TextObject("{=r2g61BjX}Well, my lads are anxiously waiting...");
        TextObject text3 = new TextObject("{=TBuyyh2S}There you go, that should be enough daggers for your men.");
        TextObject npcText5 = new TextObject("{=QCzB8DDX}Ah excellent, these will come in handy.");
        this.OfferDialogFlow = DialogFlow.CreateDialogFlow("issue_classic_quest_start").NpcLine(npcText1).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestAcceptedConsequences)).CloseDialog();
        this.DiscussDialogFlow = DialogFlow.CreateDialogFlow("quest_discuss").NpcLine(npcText2).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).BeginPlayerOptions().PlayerOption(text1).NpcLine(npcText3).CloseDialog().PlayerOption(text2).NpcLine(npcText4).CloseDialog().PlayerOption(text3).ClickableCondition(new ConversationSentence.OnClickableConditionDelegate(this.CheckPlayerHasCompletedEnoughOrdersClickableCondition)).NpcLine(npcText5).Consequence(new ConversationSentence.OnConsequenceDelegate(this.SucceedQuest)).CloseDialog().EndPlayerOptions().CloseDialog();
      }

      private bool CheckPlayerHasCompletedEnoughOrdersClickableCondition(out TextObject explanation)
      {
        if (this._completedCraftingOrders >= this._numberOfDaggersRequested)
        {
          explanation = TextObject.Empty;
          return true;
        }
        explanation = new TextObject("{=mAvJcyY1}You haven't completed enough crafting orders yet.");
        return false;
      }

      private void QuestAcceptedConsequences()
      {
        this.StartQuest();
        this._currentCraftingOrder = this.GetDaggerCraftingOrder();
        this._playerAcceptedQuestLog = this.AddDiscreteLog(this.QuestStartedLog, new TextObject("{=scjHmuyF}Complete Crafting Orders"), this._completedCraftingOrders, this._numberOfDaggersRequested);
      }

      private void CheckIfPlayerReadyToReturnItems()
      {
        if (this._playerHasNeededItemsLog == null && this._playerAcceptedQuestLog.CurrentProgress >= this._numberOfDaggersRequested)
        {
          this._playerHasNeededItemsLog = this.AddLog(this.PlayerHasNeededItemsLogText);
        }
        else
        {
          if (this._playerHasNeededItemsLog == null || this._playerAcceptedQuestLog.CurrentProgress >= this._numberOfDaggersRequested)
            return;
          this.RemoveLog(this._playerHasNeededItemsLog);
          this._playerHasNeededItemsLog = (JournalLog) null;
        }
      }

      protected override void OnTimedOut()
      {
        if (this._playerHasNeededItemsLog != null && this._playerHasNeededItemsLog.CurrentProgress >= this._numberOfDaggersRequested)
          this.SucceedQuest();
        else
          this.FailQuest();
      }

      private void SucceedQuest()
      {
        this.AddLog(this.QuestSuccessLog);
        TraitLevelingHelper.OnIssueFailed(Hero.MainHero, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Honor, 30)
        });
        this.RelationshipChangeWithQuestGiver = 5;
        this.QuestGiver.AddPower(10f);
        if (this._currentCraftingOrder != null)
          this._craftingBehavior.CancelCustomOrder(this.QuestGiver.CurrentSettlement.Town, this._currentCraftingOrder);
        GiveGoldAction.ApplyForQuestBetweenCharacters(this.QuestGiver, Hero.MainHero, this._baseGoldRewardPerDagger * this._completedCraftingOrders);
        this.CompleteQuestWithSuccess();
      }

      private void FailQuest()
      {
        this.RelationshipChangeWithQuestGiver = -5;
        this.QuestGiver.AddPower(-10f);
        this._craftingBehavior.CancelCustomOrder(this.QuestGiver.CurrentSettlement.Town, this._currentCraftingOrder);
        this.CompleteQuestWithFail(this.QuestFailedLog);
      }

      protected override void RegisterEvents()
      {
        CampaignEvents.WarDeclared.AddNonSerializedListener((object) this, new Action<IFaction, IFaction, DeclareWarAction.DeclareWarDetail>(this.OnWarDeclared));
        CampaignEvents.OnCraftingOrderCompletedEvent.AddNonSerializedListener((object) this, new Action<Town, CraftingOrder, ItemObject, Hero>(this.OnCraftingOrderCompleted));
      }

      private void OnCraftingOrderCompleted(
        Town town,
        CraftingOrder craftingOrder,
        ItemObject craftedItem,
        Hero completerHero)
      {
        if (craftingOrder != this._currentCraftingOrder)
          return;
        ++this._completedCraftingOrders;
        if (this._completedCraftingOrders == this._numberOfDaggersRequested)
        {
          TextObject textObject = new TextObject("{=T4q1DkfF}You have completed {QUEST_GIVER.NAME}'s request, you can go back to receive your reward or keep working on more orders.");
          textObject.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject);
          MBInformationManager.AddQuickInformation(textObject);
        }
        if (this._completedCraftingOrders < 10)
        {
          this._playerAcceptedQuestLog.UpdateCurrentProgress(this._completedCraftingOrders);
          this.CheckIfPlayerReadyToReturnItems();
          this._currentCraftingOrder = this.GetDaggerCraftingOrder();
        }
        else
        {
          if (this._completedCraftingOrders != 10)
            return;
          this._currentCraftingOrder = (CraftingOrder) null;
          TextObject textObject = new TextObject("{=1WbsW7I7}{QUEST_GIVER.NAME} won’t need anymore daggers. You can go back to {?QUEST_GIVER.GENDER}her{?}him{\\?} to get your reward.");
          textObject.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject);
          MBInformationManager.AddQuickInformation(textObject);
        }
      }

      private CraftingOrder GetDaggerCraftingOrder()
      {
        CraftingTemplate elementWithPredicate = CraftingTemplate.All.GetRandomElementWithPredicate<CraftingTemplate>((Func<CraftingTemplate, bool>) (x => x.TemplateName.ToString() == "Dagger"));
        CraftingOrder customOrderForHero = this._craftingBehavior.CreateCustomOrderForHero(this.QuestGiver, this.GetCraftingDifficulty(), craftingTemplate: elementWithPredicate);
        this.AddTrackedObject((ITrackableCampaignObject) customOrderForHero);
        return customOrderForHero;
      }

      private float GetCraftingDifficulty()
      {
        return MathF.Clamp((float) MathF.Min(Hero.MainHero.GetSkillValue(DefaultSkills.Crafting), 100), 10f, 100f) + (float) MBRandom.RandomInt(-10, 10);
      }

      private void OnWarDeclared(
        IFaction faction1,
        IFaction faction2,
        DeclareWarAction.DeclareWarDetail declareWarDetail)
      {
        QuestHelper.CheckWarDeclarationAndFailOrCancelTheQuest((QuestBase) this, faction1, faction2, declareWarDetail, this.QuestCanceledWarDeclaredLog, this.QuestCanceledWarDeclaredLog);
      }

      protected override void InitializeQuestOnGameLoad()
      {
        this.SetDialogs();
        this._craftingBehavior = Campaign.Current.GetCampaignBehavior<ICraftingCampaignBehavior>();
        if (this._craftingBehavior != null)
          return;
        this.CompleteQuestWithCancel();
      }

      protected override void HourlyTick()
      {
      }
    }

    public class GangLeaderNeedsSpecialWeaponsIssueTypeDefiner : SaveableTypeDefiner
    {
      public GangLeaderNeedsSpecialWeaponsIssueTypeDefiner()
        : base(596061)
      {
      }

      protected override void DefineClassTypes()
      {
        this.AddClassDefinition(typeof (GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssue), 1);
        this.AddClassDefinition(typeof (GangLeaderNeedsSpecialWeaponsIssueBehavior.GangLeaderNeedsSpecialWeaponsIssueQuest), 2);
      }
    }
  }
}
